package com.afdor.rws.event.channel.redis;

import com.afdor.rws.annotation.extension.Extension;
import com.afdor.rws.event.Event;
import com.afdor.rws.event.channel.client.consumer.handler.EventRetryStrategy;
import com.afdor.rws.event.config.EventConfigUtils;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.ToString;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.data.redis.core.RedisTemplate;

/**
 * Jedis事件重试策略
 *
 * @author 悭梵
 * @date Created in 2018-08-21 10:29
 */
@ToString
@EqualsAndHashCode
@NoArgsConstructor
@Extension(value = "jedis", order = Extension.NORMAL_ORDER - 100, scope = Extension.Scope.PROTOTYPE, interfaceClass = EventRetryStrategy.class)
public class RedisEventRetryStrategy implements EventRetryStrategy {

    @Getter
    private RedisEventConsumer redisEventConsumer;

    public RedisEventRetryStrategy(RedisEventConsumer redisEventConsumer) {
        this();
        setRedisEventConsumer(redisEventConsumer);
    }

    public RedisEventRetryStrategy setRedisEventConsumer(RedisEventConsumer redisEventConsumer) {
        this.redisEventConsumer = redisEventConsumer;
        return this;
    }

    public String getRetryResult() {
        RedisTemplate redisTemplate = this.redisEventConsumer.getRedisTemplate();
        return (String) redisTemplate.opsForList().rightPop(RedisUtils.getRetryQueueName(redisEventConsumer.getEventSourceName()));
    }

    @Override
    public void retry(@NonNull Event event) {
        /* 自动场景执行中 */
        if (StringUtils.equalsAny(event.getStatus().name(), Event.Status.EXECUTION.name())) {
            int retryNum = NumberUtils.createInteger(EventConfigUtils.getProperty(EventConfigUtils.EVENT_CONSUMER_MAX_RETRY_NUM, "3"));
            if (event.getRetryCount() >= retryNum) {
                event.setStatus(Event.Status.FAILURE_END);
            } else {
                event.addRetry();
                event.setStatus(Event.Status.FAILURE);
                this.redisEventConsumer.getRedisTemplate().opsForList().leftPush(RedisUtils.getRetryQueueName(event.getEventSourceName()), redisEventConsumer.getSerialization().serialize(event));
            }
            event.persistence();
        } else if (StringUtils.equalsAny(event.getStatus().name(), Event.Status.MANUAL_EXECUTION.name())) {
            event.setStatus(Event.Status.MANUAL_FAILURE);
            event.persistence();
        } else {
            event.persistence();
        }
    }


}
